package com.yanqu.xiuxian.config.elementalbonds;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.xiuxian.config.BaseConfigMgr;
import com.yanqu.xiuxian.config.utils.excel.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ElementalBondsConfigMgr extends BaseConfigMgr {
    private static ElementalBondsConfigMgr instance = new ElementalBondsConfigMgr();

    public static ElementalBondsConfigMgr getInstance() {
        return instance;
    }

    private int SEASON_ID_NULL = -1;

    private List<Integer> rankList = new ArrayList<>(); //段位表

    private ElementalBondsConfigMgr() {
    }

    private Map<Integer, ElementalBondsSkillConfig> skillConfigMap = new HashMap<>();
    private TreeMap<Integer, ElementalBondsScoreConfig> scoreConfigMap = new TreeMap<>();
    private Map<Integer, ElementalBondsCardConfig> cardConfigMap = new HashMap<>();
    //成就
    private Map<Integer, ElementalBondsAchieveConfig> achieveConfigMap = new HashMap<>();
   //勋章
    private Map<Integer, ElementalBondsAchieveConfig> medalConfigMap = new HashMap<>();
    //模式
    private Map<Integer, ElementalBondsModeConfig> modeConfigMap = new HashMap<>();
    //ai难度
    private Map<Integer, ElementalBondsHardLevelConfig> hardLevelConfigMap = new HashMap<>();
    private ElementalBondsHardLevelConfig checkHardLevelConfig = new ElementalBondsHardLevelConfig();
    //场景
    private Map<Integer, ElementalBondsSceneConfig> sceneConfigMap = new HashMap<>();
    //外显
    private Map<Integer, ElementalBondsCharaConfig> charaConfigMap = new HashMap<>();

    // 自己的参数
    private int colorNum = 6;                                                                   // 颜色总数
    private int blockListWidth = 7;                                                             // 盘面宽度
    private int blockListHeight = 7;                                                            // 盘面高度
    private int maxRecordNum = 50;
    private int rookieScore;
    // AI可选卡片，写完一个加一个
    private Set<Integer> aiCardSet = new HashSet<>(StringUtils.stringToIntegerList("1,2,4,5,7,8,12,13,15,17,18,19,20,21,22", ","));

    @Override
    public void refresh() {
        initScoreConfig();
        initSkillConfig();
        initCardConfig();
        initAchieveConfig();
        initSceneConfig();
        initModeConfig();
        initCharaConfig();
        this.hardLevelConfigMap = JSON.parseObject(       // AI难度配置（用最下面的main方法生成）
                "{1:{\"cardWeight\":7000,\"hardLevel\":1,\"moveWeightList\":[-10000,-5000,0,1000,0,0,0],\"skillWeight\":500},2:{\"cardWeight\":7000,\"hardLevel\":2,\"moveWeightList\":[10000,5000,3000,1000,300,0,0],\"skillWeight\":150},3:{\"cardWeight\":7000,\"hardLevel\":3,\"moveWeightList\":[10000,5000,3000,1000,300,150,100],\"skillWeight\":275}}"
                , new TypeReference<ConcurrentHashMap<Integer, ElementalBondsHardLevelConfig>>() {
                });
        this.checkHardLevelConfig = JSON.parseObject(       // 用于检查初始盘面的难度参数（用最下面的main方法生成）
                "{\"cardWeight\":0,\"hardLevel\":-1,\"moveWeightList\":[10000,0,0,0,0,0,0],\"skillWeight\":0}"
                , new TypeReference<ElementalBondsHardLevelConfig>() {
                });
    }
    private void initScoreConfig() {
        List<ElementalBondsScoreConfig> tempElementalBondsConfigList = init(ElementalBondsScoreConfig.class);
        TreeMap<Integer, ElementalBondsScoreConfig> tempElementalBondsScoreMap = new TreeMap<>();
        TreeMap<Integer,Integer> sortedMap = new TreeMap<>();
        int rookieScore = 0;
        for (ElementalBondsScoreConfig config : tempElementalBondsConfigList) {
            tempElementalBondsScoreMap.put(config.getId(), config);
            sortedMap.put(config.getId(),config.getPoints());
            if (config.getSeason() == 0) {
                rookieScore = Math.max(config.getPoints(), rookieScore);
            }
        }
        rankList = new ArrayList<>(sortedMap.values());
        this.scoreConfigMap = tempElementalBondsScoreMap;
        this.rookieScore = rookieScore;
    }

    private void initSkillConfig() {
        List<ElementalBondsSkillConfig> tempElementalBondsConfigList = init(ElementalBondsSkillConfig.class);
        Map<Integer, ElementalBondsSkillConfig> tempElementalBondsScoreMap = new HashMap<>();
        for (ElementalBondsSkillConfig config : tempElementalBondsConfigList) {
            tempElementalBondsScoreMap.put(config.getId(), config);
        }
        this.skillConfigMap = tempElementalBondsScoreMap;
    }

    private void initCardConfig() {
        List<ElementalBondsCardConfig> tempElementalBondsConfigList = init(ElementalBondsCardConfig.class);
        Map<Integer, ElementalBondsCardConfig> tempElementalBondsScoreMap = new HashMap<>();
        for (ElementalBondsCardConfig config : tempElementalBondsConfigList) {
            tempElementalBondsScoreMap.put(config.getCardId(), config);
        }
        this.cardConfigMap = tempElementalBondsScoreMap;
    }

    private void initAchieveConfig() {
        List<ElementalBondsAchieveConfig> tempElementalBondsConfigList = init(ElementalBondsAchieveConfig.class);
        Map<Integer, ElementalBondsAchieveConfig> tempElementalBondsAchieveConfigMap = new HashMap<>();
        Map<Integer, ElementalBondsAchieveConfig> tempElementalBondsMedalConfigMap = new HashMap<>();
        for (ElementalBondsAchieveConfig config : tempElementalBondsConfigList) {
            if (config.getType() == 0) {
                tempElementalBondsAchieveConfigMap.put(config.getId(), config);
            }else {
                tempElementalBondsMedalConfigMap.put(config.getId(), config);
            }
        }
        this.achieveConfigMap = tempElementalBondsAchieveConfigMap;
        this.medalConfigMap = tempElementalBondsMedalConfigMap;
    }

    private void initModeConfig() {
        List<ElementalBondsModeConfig> tempElementalBondsConfigList = init(ElementalBondsModeConfig.class);
        Map<Integer, ElementalBondsModeConfig> tempElementalBondsScoreMap = new HashMap<>();
        for (ElementalBondsModeConfig config : tempElementalBondsConfigList) {
            tempElementalBondsScoreMap.put(config.getModeId(), config);
        }
        this.modeConfigMap = tempElementalBondsScoreMap;
    }

    private void initSceneConfig() {
        List<ElementalBondsSceneConfig> tempElementalBondsConfigList = init(ElementalBondsSceneConfig.class);
        Map<Integer, ElementalBondsSceneConfig> tempElementalBondsSceneConfigMap = new HashMap<>();
        for (ElementalBondsSceneConfig config : tempElementalBondsConfigList) {
            tempElementalBondsSceneConfigMap.put(config.getId(), config);
        }
        this.sceneConfigMap = tempElementalBondsSceneConfigMap;
    }

    public void initCharaConfig() {
        List<ElementalBondsCharaConfig> tempElementalBondsCharaConfigList = init(ElementalBondsCharaConfig.class);
        Map<Integer, ElementalBondsCharaConfig> tempElementalBondsCharaConfigMap = new HashMap<>();
        for (ElementalBondsCharaConfig config : tempElementalBondsCharaConfigList) {
            tempElementalBondsCharaConfigMap.put(config.getId(), config);
        }
        this.charaConfigMap = tempElementalBondsCharaConfigMap;
    }

    public Map<Integer, ElementalBondsAchieveConfig> getAchieveConfigMap() {
        return achieveConfigMap;
    }
    public Map<Integer, ElementalBondsSkillConfig> getSkillConfigMap() {
        return skillConfigMap;
    }

    public Map<Integer, ElementalBondsCardConfig> getCardConfigMap() {
        return cardConfigMap;
    }

    public List<Integer> getRankList() {
        return rankList;
    }

    public TreeMap<Integer, ElementalBondsScoreConfig> getScoreConfigMap() {
        return scoreConfigMap;
    }

    public Map<Integer, ElementalBondsModeConfig> getModeConfigMap() {
        return modeConfigMap;
    }

    public Map<Integer, ElementalBondsHardLevelConfig> getHardLevelConfigMap() {
        return hardLevelConfigMap;
    }

    public Map<Integer, ElementalBondsSceneConfig> getSceneConfigMap() {
        return sceneConfigMap;
    }

    public Map<Integer, ElementalBondsAchieveConfig> getMedalConfigMap() {
        return medalConfigMap;
    }

    public Map<Integer, ElementalBondsCharaConfig> getCharaConfigMap() {
        return charaConfigMap;
    }

    public ElementalBondsAchieveConfig getMedalConfigByCompleteType(int type) {
        return medalConfigMap.values().stream().filter(config -> config.getCompleteType() == type).findFirst().orElse(null);
    }
    public int getSeasonIdNull() {
        return SEASON_ID_NULL;
    }

    public ElementalBondsHardLevelConfig getCheckHardLevelConfig() {
        return checkHardLevelConfig;
    }

    public int getColorNum() {
        return colorNum;
    }

    public int getBlockListWidth() {
        return blockListWidth;
    }

    public int getBlockListHeight() {
        return blockListHeight;
    }

    public int getRookieScore() {
        return rookieScore;
    }

    public Set<Integer> getAiCardSet() {
        return aiCardSet;
    }

    // 获取段位
    public ElementalBondsScoreConfig getScoreConfig(long score, boolean guide) {
        int rankId = 0;
        int configId = 0;
        for (ElementalBondsScoreConfig rankConfig : scoreConfigMap.values()) {
            boolean isGuideRank = rankConfig.getSeason() == 0;
            if (isGuideRank != guide) {
                continue; // 新手只能拿新手段位，非新手只能拿非新手
            }
            if (score >= rankConfig.getPoints()) {
                configId = rankConfig.getId();
            }
        }
        if (configId != 0) {
            return scoreConfigMap.get(configId);
        }
        //取最大，一个是超分，一个是没有赛季
        if (scoreConfigMap.containsKey(scoreConfigMap.size())) {
            return scoreConfigMap.get(scoreConfigMap.size());
        }
        return null;
    }

    public int getMaxRecordNum() {
        return maxRecordNum;
    }

    public List<ElementalBondsCardConfig> getCardConfigByQuality(int quality) {
        return cardConfigMap.values().stream().filter(config -> config.getQuality() == quality).collect(Collectors.toList());
    }

    public List<ElementalBondsCardConfig> getCanRandomCardConfigByQuality(int quality) {
        return cardConfigMap.values().stream().filter(config -> config.getQuality() == quality && config.getSpecial() > 0).collect(Collectors.toList());
    }

    public ElementalBondsCardConfig getCardConfigByItemId(int itemId) {
        return cardConfigMap.values().stream().filter(config -> config.getItemId() == itemId).findFirst().orElse(null);
    }

    public ElementalBondsSkillConfig getSkillConfigByItemId(int itemId) {
        return skillConfigMap.values().stream().filter(config -> config.getItemId() == itemId).findFirst().orElse(null);
    }

    public int getCardQuality(int cardId) {
        ElementalBondsCardConfig cardConfig = cardConfigMap.get(cardId);
        if (cardConfig != null) {
            return cardConfig.getQuality();
        }
        return 0;
    }

    public ElementalBondsAchieveConfig getAchievementConfigByCompleteType(int type) {
        return achieveConfigMap.values().stream().filter(config -> config.getCompleteType() == type).findFirst().orElse(null);
    }

    public int getElementalBondsSkillRandomItemId() {
        List<Integer> itemIdList = skillConfigMap.values().stream()
                .map(ElementalBondsSkillConfig::getItemId)
                .collect(Collectors.toList());
        return itemIdList.isEmpty() ? 0 : itemIdList.get(new Random().nextInt(itemIdList.size()));
    }

    public int getElementalBondsCardRandomItemId(int quality, Random random) {
        List<Integer> itemIdList = cardConfigMap.values().stream()
                .filter(elementalBondsCardConfig -> elementalBondsCardConfig.getQuality() == quality)
                .map(ElementalBondsCardConfig::getItemId)
                .collect(Collectors.toList());
        return itemIdList.isEmpty() ? 0 : itemIdList.get(random.nextInt(itemIdList.size()));
    }

}
